Informática 2015-2016

Práctica Obligatoria 2

Grupos A,B,C,D,E
1º de Grados
Facultad de Matemáticas, UCM

Motivación

Seguro que en alguna ocasión (o en muchas) has utilizado Google Maps o Google Street View. Quizás te has fijado en que las caras de las personas y las matrículas de los coches, o incluso zonas enteras no se ven con claridad.

Estos fragmentos de imágenes están tratados digitalmente para perder el detalle de esas zonas. Los efectos utilizados suelen ser el difuminado y el pixelado. Los dos son similares, pero en esta práctica nos centraremos en el pixelado de imágenes.

También, en otras ocasiones, el pixelado puede ser un efecto estético que se busca. Por ejemplo, podríamos querer transformar una imagen de Mario Bros y Luigi para que nos recordase más a la estética original de Nintendo.

O puede ser un recurso artístico.

Objetivos de la práctica

En esta práctica queremos desarrollar las funciones necesarias para poder pixelar una imagen. En las secciones siguientes te explicaremos todo lo necesario para saber cómo hacer el pixelado y te daremos algunos ejemplos.

¿Cómo se hace?

Las imágenes están compuestas de píxeles y cada píxel almacena un valor numérico que codifica el color. En la siguiente imagen puedes ver una zona aumentada de una fotografía y los píxeles que se encuentran en esa zona.

zoom a los píxeles de una imagen

Para imágenes en blanco y negro este valor es un único número, pero para imágenes en color cada píxel contiene una terna de valores. Vamos a suponer que estamos trabajando con imágenes en blanco y negro y que el rango de valores de cada píxel es de 0 a 255. La imagen siguiente muestra los valores de la matriz de valores asociada a la zona de la imagen destacada con un pequeño recuadro blanco en el retrovisor.

matriz de valores de una imagen

Básicamente, el pixelado consiste en hacer que la imagen parezca que tiene unos bloques constituyentes mayores. Para ello, hay que hacer que todos los valores de una submatriz tomen el mismo valor. Volviendo al ejemplo de la imagen anterior, el del coche, el pixelado podría sustituir todos los valores de la matriz del fragmento del retrovisor por un único valor, por ejemplo, el valor medio de todos ellos. Pero la elección del valor de sustitución para los elementos de la submatriz puede ser otro, podríamos asignar a todos los valores de la sumatriz del ejemplo el mínimo de los valores que aparecen en la submatriz, o el máximo...

A continuación te mostramos una imagen y el efecto que provocamos al elegir como valor de sustitución para el pixelado el valor medio de los elementos de las submatrices, el valor mínimo y el valor máximo, respectivamente.



Pero una cuestión esencial es que también necesitamos saber cuál es la dimensión de las submatrices que deseamos considerar. Esto nos dará lo grueso que es el pixelado. Por ejemplo, no es lo mismo pixelar con una matriz 4x4 que con 15x15. A continuación puedes ver una imagen y el resultado de pixelar utilizando dimensiones 5x5, 15x15 y 30x30. Todas ellas con el valor medio de los puntos que componen las submatrices.



¿Qué se pide?

Como hemos visto en el apartado anterior, para poder pixelar una imagen necesitamos varios parámetros: obviamente una imagen, el tamaño de la submatriz, y el modo que utilizaremos para hacer la unificación de valores.

Concretando, lo que deseamos es que programes una función que dada una imagen devuelva una nueva imagen pixelada. La función tiene que llamarse pixelate(img, (pixel_width, pixel_height), mode) y tiene que devolver una nueva imagen con el resultado del pixelado. Los parámetros de la función son:

Ejemplos gráficos

Veamos algunos ejemplos de los resultados de la función pixelate con algunas imágenes.

Comenzamos con una imagen muy sencilla. Tiene unas dimensiones de 200x200 píxeles y unos escaques o casillas de 100x100 píxeles.

Supongamos que img es una variable que tiene la imagen anterior. Veamos el resultado de las siguientes llamadas a la función pixelate.

Seguimos con una imagen muy simétrica. Tiene unas dimensiones de 200x200 píxeles y unos escaques o casillas cuadradas de 10x10 píxeles.

Hay un montón de llamadas a la función pixelate que dan como resultado la misma imagen. Supongamos que img es una variable que tiene la imagen anterior, todas las llamadas siguientes devolverían exactamente la misma imagen de partida:

pixelate(img, (10, 10), 'mean')

pixelate(img, (5, 5), 'max')

pixelate(img, (2, 2), 'min')

pixelate(img, (1, 1), 'mean')

Pero no siempre es así, por ejemplo pixelate(img, (11, 11), 'mean') devuelve esta imagen:

otras llamadas interesantes con su resultados son estas:

Por supuesto, las dimensiones de los bloques de píxeles no tienen porqué ser siempre cuadrados. Aquí van unos ejemplos con dimensiones rectangulares.

Para no aburrirse

El problema propuesto no es demasido difícil. De forma opcional os proponemos algunas extensiones interesantes: